package com.zb.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zb.entity.base.JsonCommon;
import com.zb.entity.base.OmsCommonParam;
import com.zb.entity.system.OmsOperList;
import com.zb.mvc.controller.base.BaseAction;
import com.zb.util.annotation.AnnotationUtils;

import org.apache.commons.lang3.StringUtils;

/**
 * Mvc的使用的工具类
 *
 * @author Administrator
 */
public final class ActionUtils
{

	static final String USERKEY = "oms_user_key123";

	/**
	 * 构建公共分页查询参数
	 *
	 * @param request
	 * @param isQueryTotal
	 * @return
	 */
	public static OmsCommonParam buildQueryParam(HttpServletRequest request, boolean isQueryTotal)
	{
		OmsCommonParam returnParam = new OmsCommonParam();
		returnParam.setQueryTotal(isQueryTotal);
		returnParam.setSortName(request.getParameter(BaseAction.CommonParam.SORT_NAME));
		String sortValue = request.getParameter(BaseAction.CommonParam.SORT_VALUE);
		String pageNo = request.getParameter(BaseAction.CommonParam.PAGE_NO);
		String pageSize = request.getParameter(BaseAction.CommonParam.PAGE_SIZE);
		if (StringUtils.isNumeric(sortValue))
		{
			returnParam.setSortValue(Integer.parseInt(sortValue));
		}

		if (StringUtils.isNumeric(pageNo) && StringUtils.isNumeric(pageSize))
		{
			returnParam.setPageNo(Integer.parseInt(pageNo));
			returnParam.setPageSize(Integer.parseInt(pageSize));
		}

		return returnParam;
	}

	public static <T> T getParamInstance(Class<T> cls, Map<String, String> paramsMap, String sysid, boolean isCreate, boolean isFind)
	{
		//所有属性
		Field fields[] = cls.getDeclaredFields();
		try
		{
			//获取没参数的默认构造器
			Constructor<T> cstr = cls.getConstructor();
			T obj = cstr.newInstance();
			for (Field field : fields)
			{
				if (!AnnotationUtils.ignore(field) && !ReflectUtils.judgeModifiersAvailable(field))
				{
					allFieldsWrite(field, obj, isCreate, sysid, paramsMap.entrySet(), isFind);
				}
			}

			return obj;
		}
		catch (NoSuchMethodException e)
		{
			e.printStackTrace();
		}
		catch (SecurityException e)
		{
			e.printStackTrace();
		}
		catch (InstantiationException e)
		{
			e.printStackTrace();
		}
		catch (IllegalAccessException e)
		{
			e.printStackTrace();
		}
		catch (IllegalArgumentException e)
		{
			e.printStackTrace();
		}
		catch (InvocationTargetException e)
		{
			e.printStackTrace();
		}
		catch (IntrospectionException e)
		{
			e.printStackTrace();
		}
		return null;
	}

	private static <T> void executeWriteMethod(Field field, String value, T obj) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	{
		PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass());
		Method wM = pd.getWriteMethod();//获得写方法
		Object lastValue = null;
		if (String.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = value;
		}
		else if (null == value  || "".equals(value) )
		{
			lastValue = null ;
		}
		else if (Integer.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = Integer.parseInt(value);
		}
		else if (Long.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = Integer.parseInt(value);
		}
		else if (Boolean.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = Boolean.parseBoolean(value);
		}
		else if (Float.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = Float.parseFloat(value);
		}
		else if (Double.class.isAssignableFrom((Class<?>) field.getGenericType()))
		{
			lastValue = Double.parseDouble(value);
		}
		else
		{
			return;
		}
		wM.invoke(obj, lastValue);
	}

	private static <T> void allFieldsWrite(Field field, T obj, boolean isCreate, String sysid, Set<Entry<String, String>> paramEntrys, boolean isFind)
			throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	{
		if (!isFind)
		{
			if (isCreate)
			{
				if ("create_oper_id".equals(field.getName()))
				{
					executeWriteMethod(field, sysid, obj);
				}
				else if ("create_time".equals(field.getName()))
				{
					executeWriteMethod(field, new Date(), obj);
				}
				else if ("valid_flag".equals(field.getName()))
				{
					executeWriteMethod(field, 1, obj);
				}
			}

			if ("update_oper_id".equals(field.getName()))
			{
				executeWriteMethod(field, sysid, obj);
			}
			else if ("oper_id".equals(field.getName()))
			{
				executeWriteMethod(field, sysid, obj);
			}
			else if ("update_time".equals(field.getName()))
			{
				executeWriteMethod(field, new Date(), obj);
			}
			else if ("set_time".equals(field.getName()))
			{
				executeWriteMethod(field, new Date(), obj);
			}
		}
		for (Entry<String, String> paramEntry : paramEntrys)
		{
			if (field.getName().equals(paramEntry.getKey()) && field.getGenericType() instanceof Class<?>)
			{
				executeWriteMethod(field, paramEntry.getValue(), obj);
			}
		}
	}

	private static <T> void executeWriteMethod(Field field, Object value, T obj) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	{
		PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass());
		Method wM = pd.getWriteMethod();//获得写方法
		wM.invoke(obj, value);
	}

	/**
	 * 此方法只用户获取单个参数传递的值
	 *
	 * @param request
	 * @return
	 */
	public static Map<String, String> getParameterMap(HttpServletRequest request)
	{
		Map<String, String> map = new HashMap<>();
		Enumeration<String> paramNames = request.getParameterNames();
		while (paramNames.hasMoreElements())
		{
			String paramName = (String) paramNames.nextElement();

			String[] paramValues = request.getParameterValues(paramName);
			try
			{
				if (paramValues.length == 1)
				{
					map.put(paramName, URLDecoder.decode(paramValues[0], "utf-8"));
				}
				//			      else
				//			      {
				//			    	  String values = StringUtils.join(paramValues, ",");
				//			      }
			}
			catch (UnsupportedEncodingException e)
			{
				continue;
			}
		}
		//查询都是有效信息
		//	    map.put("valid_flag", "1");
		return map;
	}

	public static String genarateUserToken(OmsOperList user)
	{
		String json = JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat);
		try
		{
			return DzDigester.desEncrypt(json, USERKEY);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}

	public static OmsOperList parseUserToken(String userToken)
	{

		try
		{
			String userJson = DzDigester.desDecrypt(userToken, USERKEY);
			return JSON.parseObject(userJson, OmsOperList.class);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}

	public static void sendJson2Client(HttpServletResponse response, JsonCommon<?> jc)
	{
		response.setCharacterEncoding("utf-8");
		PrintWriter writer = null;
		try
		{
			writer = response.getWriter();
			writer.print(JSON.toJSONStringWithDateFormat(jc, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			writer.flush();
		}
		catch (IOException e)
		{
		}
		finally
		{
			if (writer != null)
			{
				writer.close();
			}
		}
	}

	public static boolean isAjaxRequest(HttpServletRequest request)
	{
		return request.getHeader("x-requested-with") != null && "XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"));
	}

	public static void doSystemAction(HttpServletRequest request, HttpServletResponse response, String toPath, JsonCommon<?> jc) throws IOException
	{
		if (isAjaxRequest(request))
		{
			sendJson2Client(response, jc);
		}
		else
		{
			try
			{
				String path = request.getContextPath();
				response.sendRedirect(path + toPath);
			}
			catch (IOException e)
			{
				throw e;
			}
		}
	}

	public static void main(String[] args)
	{
		System.out.println(parseUserToken(
				"CcRmdqKgQXyXjc+sulg9G2irmEDfChAf3ZWfCvZyyLZz+xvOYjp9T3tPSvamuIzyX/95tq5RhapkTe5+llvRnbpiYpeJfaBukAPCXIfvAaTxABFtY9aFB1A0DQDST39aed2EDngZiXxotfX0n4GHQILf+FgDc71iKHRvqtBqeUGzaZzMkUoxXBXxxu53/zI3TpUdYqcZBqZGBR1RvPELKq3Ak6sFn3+vgqBKw1HJq8sgAbXJwnSfiqM6WrjFzDAaIFKJkeECiQIBmp2RCQHe9UapiRsGfSszCLa5ky6Ga303CV4JrVzpeIXUeF0fmRYl/EGZDgAMOTvSZl6CQZWHGfKqiwvHV5bWUbqWlSjaS7g="));
	}

}
